package com.kmx.demo.datagen;

import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.Format;

import org.apache.commons.lang3.RandomUtils;

import com.alibaba.fastjson.JSONObject;
import com.kmx.demo.utils.DateUtils;
import com.kmx.demo.utils.K2FileUtils;
import com.kmx.demo.utils.NumericUtils;

public class GenDataThread extends Thread {
	final String uuid;
	String fgId;
	long startTime;
	long endTime;
	long dataFreq;
	int assetNum;
	String terminator;
	String dataLocation;
	boolean containEX;

	public GenDataThread(String uuid, String fgId, long startTime, long endTime, long dataFreq, int assetNum,
			String terminator, String dataLocation, boolean containEX) {
		super();
		this.uuid = uuid;
		this.fgId = fgId;
		this.startTime = startTime;
		this.endTime = endTime;
		this.dataFreq = dataFreq;
		this.assetNum = assetNum;
		this.terminator = terminator;
		this.dataLocation = dataLocation;
		this.containEX = containEX;
	}

	public void run() {

		JSONObject angle = new JSONObject();
		JSONObject power = new JSONObject();
		JSONObject generator = new JSONObject();
		String fgSuffix = fgId.replace("windfarm_" + uuid + "_", "");
		long currentTime = startTime;
		FileWriter writer = null;
		double windSpeed = 3;
		String windSpeed_str = "3";
		double pitchAngle = 0;
		String pitchAngle_str = "0";
		double generatorSpeed = 10;
		String generatorSpeed_str = "10";
		double powerActive = 25;
		String powerActive_str = "25.6888";
		long flagTime = currentTime;
		double windSpeedFlag = 3;
		double lastWind = 3;
		boolean addFlag = true;
		boolean genIntervalFlag = true;
		double interval=1728000000;
		int lostFlag = 0;
		long initTime = startTime;

		try {
			writer = new FileWriter(K2FileUtils.filePath(dataLocation) + fgId + ".csv", true);
		} catch (Exception e) {
			e.printStackTrace();
		}

		while (currentTime <= endTime) {

			for (int i = 0; i < assetNum; i++) {
				String content = "";
				String turbineId = "turbine_" + fgSuffix + "_" + uuid + "_" + format(i + 1);
				if (addFlag) {
					if (currentTime - flagTime < 600000) {
						windSpeed = NumericUtils.doubleWithScale(windSpeedFlag * RandomUtils.nextDouble(0.8, 1.2), 2,
								BigDecimal.ROUND_HALF_UP);
						lastWind = windSpeed;
						windSpeed_str = windSpeed + "";
						if (windSpeed < 3) {
							windSpeed=RandomUtils.nextDouble(2.5,3);
							windSpeed_str = windSpeed+"";
						}
						if (windSpeed > 11) {
							windSpeed=RandomUtils.nextDouble(10.5, 11.5);
							windSpeed_str = windSpeed+"";
						}
					} else {
						flagTime = currentTime;
						windSpeed = lastWind + NumericUtils.doubleWithScale(RandomUtils.nextFloat(0.1f, 0.2f), 2,
								BigDecimal.ROUND_HALF_UP);
						windSpeed_str = windSpeed + "";
						windSpeedFlag = windSpeed;

					}

					if (windSpeed > 11) {

						addFlag = false;
						
						windSpeed=RandomUtils.nextDouble(11, 11.5);
					}

				} else {

					if (currentTime - flagTime < 600000) {
						windSpeed = NumericUtils.doubleWithScale(windSpeedFlag * RandomUtils.nextDouble(0.8, 1.2), 2,
								BigDecimal.ROUND_HALF_UP);
						lastWind = windSpeed;
						windSpeed_str = windSpeed + "";
						if (windSpeed < 3) {
							windSpeed=RandomUtils.nextDouble(2.5,3);
							windSpeed_str = windSpeed+"";
						}
						if (windSpeed > 11) {
							windSpeed=RandomUtils.nextDouble(11, 11.5);
							windSpeed_str = windSpeed+"";
						}
					} else {
						flagTime = currentTime;
						windSpeed = lastWind - NumericUtils.doubleWithScale(RandomUtils.nextFloat(0.1f, 0.2f), 2,
								BigDecimal.ROUND_HALF_UP);
						windSpeed_str = windSpeed + "";
						windSpeedFlag = windSpeed;
					}

					if (windSpeed < 2.5) {

						addFlag = true;
					}

				}
				if(windSpeed>11){
					
					windSpeed=RandomUtils.nextDouble(10.5, 11.5);
					windSpeed_str = windSpeed+"";
				}

				if (windSpeed > 4.7 && windSpeed < 8.2) {
					generatorSpeed = (windSpeed * 2) * (NumericUtils.doubleWithScale(RandomUtils.nextDouble(1, 1.1), 4,
							BigDecimal.ROUND_HALF_UP));

					generatorSpeed = NumericUtils.doubleWithScale(generatorSpeed, 4, BigDecimal.ROUND_HALF_UP);
					generatorSpeed_str = generatorSpeed + "";
				} else if (windSpeed >= 8.2) {
					generatorSpeed_str = "17.3";
				} else {
					generatorSpeed_str = "10";
				}
				if (windSpeed >= 10.7) {
					powerActive_str = "1500";
					if (windSpeed < 11.5) {
						pitchAngle = ((((windSpeed - 10.7) / 0.1) * 0.4) + 0.561391) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.91, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					else if (windSpeed >= 11.5 && windSpeed < 12.5) {
						pitchAngle = ((((windSpeed - 11.5) / 0.1) * 0.3) + 3.71963) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.92, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					else if (windSpeed >= 12.5 && windSpeed < 13.5) {
						pitchAngle = ((((windSpeed - 12.5) / 0.1) * 0.2) + 6.4234) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.93, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					else if (windSpeed >= 13.5 && windSpeed < 16.5) {
						pitchAngle = ((((windSpeed - 13.5) / 0.1) * 0.18) + 8.6621) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.94, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					else if (windSpeed >= 16.5 && windSpeed < 18.3) {
						pitchAngle = ((((windSpeed - 16.5) / 0.1) * 0.15) + 14.0555) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.95, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					else if (windSpeed >= 18.3 && windSpeed < 21.9) {
						pitchAngle = ((((windSpeed - 18.3) / 0.1) * 0.13) + 16.797) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.96, 0.99), 4, BigDecimal.ROUND_HALF_UP));
					}

					pitchAngle = NumericUtils.doubleWithScale(pitchAngle, 4, BigDecimal.ROUND_HALF_UP);
					if (windSpeed == 21.9 || pitchAngle > 21.6361) {
						pitchAngle_str = "21.6361";

					} else {
						pitchAngle_str = pitchAngle + "";
					}
				} else {
					pitchAngle_str = "0";
				}

				if (windSpeed < 10.7) {
					if (windSpeed >= 3 && windSpeed < 4) {
						powerActive = 25 + (((windSpeed - 3) / 0.1) * 7) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (windSpeed >= 4 && windSpeed < 5) {
						powerActive = 80 + (((windSpeed - 4) / 0.1) * 10) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (windSpeed >= 5 && windSpeed < 6) {
						powerActive = 180 + (((windSpeed - 5) / 0.1) * 12) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}
					if (windSpeed >= 6 && windSpeed < 7) {
						powerActive = 305 + (((windSpeed - 6) / 0.1) * 20) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (windSpeed >= 7 && windSpeed < 8) {
						powerActive = 488.225 + (((windSpeed - 7) / 0.1) * 23) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (windSpeed >= 8 && windSpeed < 9) {
						powerActive = 733.948 + (((windSpeed - 8) / 0.1) * 27) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (windSpeed >= 9 && windSpeed < 10.7) {
						powerActive = 1012.99 + (((windSpeed - 9) / 0.1) * 30) * (NumericUtils
								.doubleWithScale(RandomUtils.nextDouble(0.7, 0.99), 4, BigDecimal.ROUND_HALF_UP));
						powerActive_str = powerActive + "";
					}

					if (powerActive >= 1500) {
						powerActive = 1500 * RandomUtils.nextDouble(0.9, 0.99);
						powerActive_str = powerActive + "";
					}

					powerActive = NumericUtils.doubleWithScale(powerActive, 4, BigDecimal.ROUND_HALF_UP);
					powerActive_str = powerActive + "";
				}
				if (!angle.containsKey(windSpeed_str)) {
					angle.put(windSpeed_str, pitchAngle_str);
				}
				if (!power.containsKey(windSpeed_str)) {
					power.put(windSpeed_str, powerActive_str);
				}
				if (!generator.containsKey(windSpeed_str)) {
					generator.put(windSpeed_str, generatorSpeed_str);
				}

				content = fgId + terminator + turbineId + terminator + DateUtils.convertTimestampToISO(currentTime)
						+ terminator + windSpeed_str + terminator + power.getString(windSpeed_str) + terminator
						+ generator.getString(windSpeed_str) + terminator + angle.getString(windSpeed_str);
				
				try {
//					if(genIntervalFlag){
//						
//						interval=interval*RandomUtils.nextDouble(0.8,1.2);
//					}
					
					if (currentTime - initTime > interval) {

						lostFlag = RandomUtils.nextInt(100, 200);
						initTime = currentTime;
						genIntervalFlag=false;
					}
					if (lostFlag == 0) {
						writer.write(content + "\n");
					} else {
						lostFlag--;
						if(lostFlag==0){
							
							genIntervalFlag=true;
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
			currentTime = currentTime + dataFreq;

		}

		if (writer != null)

		{
			try {
				writer.close();
			} catch (

			IOException e)

			{
				e.printStackTrace();
			}

		}

		if (containEX)

		{
			String errorFgId = fgId + "error";
			String errorAssetId = "turbine_err_" + fgSuffix + "_" + uuid + "_" + format(0 + 1);
			currentTime = currentTime + dataFreq;
			String fgLost = errorFgId + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1)
					+ terminator + DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str
					+ terminator + power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str)
					+ terminator + angle.getString(windSpeed_str);
			currentTime = currentTime + dataFreq;
			String assetLost = fgId + terminator + errorAssetId + terminator
					+ DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str + terminator
					+ power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str) + terminator
					+ angle.getString(windSpeed_str);
			currentTime = currentTime + dataFreq;

			String recordLengthError = fgId + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1)
					+ terminator + DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str
					+ terminator + power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str)
					+ terminator + angle.getString(windSpeed_str) + terminator + "2";

			currentTime = currentTime + dataFreq;
			String recordLengthError1 = fgId + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1)
					+ terminator + DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str
					+ terminator + power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str);

			currentTime = currentTime + dataFreq;
			String dataTypeError = fgId + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1)
					+ terminator + DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str
					+ terminator + power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str)
					+ terminator + "Err-011";

			currentTime = currentTime + dataFreq;
			String blank = "";
			currentTime = currentTime + dataFreq;
			String dateEx = fgId + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1) + terminator
					+ currentTime + terminator + windSpeed_str + terminator + power.getString(windSpeed_str)
					+ terminator + generator.getString(windSpeed_str) + terminator + angle.getString(windSpeed_str)
					+ "\n";

			currentTime = currentTime + dataFreq;
			String fgIdEx = "" + terminator + "turbine_" + fgSuffix + "_" + uuid + "_" + format(0 + 1) + terminator
					+ DateUtils.convertTimestampToISO(currentTime) + terminator + windSpeed_str + terminator
					+ power.getString(windSpeed_str) + terminator + generator.getString(windSpeed_str) + terminator
					+ angle.getString(windSpeed_str);

			String[] errorRecord = { fgLost, assetLost, recordLengthError, recordLengthError1, dataTypeError, blank,
					dateEx, fgIdEx };

			for (int i = 0; i < errorRecord.length; i++) {

				K2FileUtils.writeContentsToFile(K2FileUtils.filePath(dataLocation) + fgId + ".csv",
						errorRecord[i] + "\n", true);

			}
		}

	}

	private static String format(int number) {
		Format f = new DecimalFormat("000");
		return f.format(number);
	}
}
